package obecto.task
{
	import flash.utils.clearTimeout;
	
	import obecto.event.TaskEvent;
	import obecto.event.TaskEventKind;

	[Event(name="interrupt", type="obecto.event.TaskEvent")]

	public class BaseInterruptibleTask extends BaseTask implements IInterruptibleTask
	{
		protected var _reversing : Boolean = false;
		
		public function BaseInterruptibleTask()
		{
			super();
		}
		
		public function end() : void
		{
			if (running == true)
			{
				dispatchEvent(new TaskEvent(TaskEvent.INTERRUPT, TaskEventKind.END));					
			}
			
			_reversing = false;
			complete();
		}
		
		public function interrupt() : void
		{
			if (running == true)
			{	
				if (!isNaN(delayId))
				{
					clearTimeout(delayId);
					delayId = NaN;
				}
				
				_running = false;
				_reversing = false;							
				dispatchEvent(new TaskEvent(TaskEvent.INTERRUPT, TaskEventKind.INTERRUPT));
			}		
		}
		
		public function reverse() : void
		{
			if (reversing == false)
			{
				_reversing = true;
				
				reverseActual();
				
				if (running == true)
				{	
					dispatchEvent(new TaskEvent(TaskEvent.INTERRUPT, TaskEventKind.REVERSE));
				}
				else
				{
					_running = true;
					dispatchEvent(new TaskEvent(TaskEvent.START, TaskEventKind.REVERSE));
				}
			}
		}
		
		virtual protected function reverseActual() : void
		{
		}
		
		public function forward() : void
		{
			if (_running == true && _reversing == true)
			{
				_reversing = false;
				
				forwardActual();
				
				dispatchEvent(new TaskEvent(TaskEvent.START, TaskEventKind.FORWARD));
			}
		}
		
		virtual protected function forwardActual() : void
		{
		}
		
		public function rollback() : void
		{
			if (running == true)
			{
				_reversing = true;
				dispatchEvent(new TaskEvent(TaskEvent.INTERRUPT, TaskEventKind.ROLLBACK));
			}			
		
			completeReverse();
		}
		
		public function get reversing() : Boolean
		{
			return _reversing;
		}
		
		protected function completeReverse() : void
		{
			_running = false;
			_reversing = false;
			
			dispatchEvent(new TaskEvent(TaskEvent.COMPLETE, TaskEventKind.REVERSE))			
		}		
	}
}